package amazon;

import org.junit.Test;

import static junit.framework.Assert.assertEquals;

/**
 * Created by richard on 5/8/14.
 */
public class DelComment {
    @Test
    public void verify(){
        DelComment delComment = new DelComment();
        String result = DelComment.delComments2("#include <stdio.h>\n" +
                "\n" +
                "int main()\n" +
                "{\n" +
                "    int x = 0;\n" +
                "    // print x\n" +
                "    printf(\"%d\", x);\n" +
                "    /* return 0 */\n" +
                "    return 0;\n" +
                "}");

        assertEquals("#include <stdio.h>\n" +
                "\n" +
                "int main()\n" +
                "{\n" +
                "    int x = 0;\n" +
                "    \n" +
                "    printf(\"%d\", x);\n" +
                "    \n" +
                "    return 0;\n" +
                "}",
                result);
    }


    public static char[] del(char[] _target, int _start, int _end) {
        char[] tmp = new char[_target.length - (_end - _start + 1)];
        System.arraycopy(_target, 0, tmp, 0, _start);
        System.arraycopy(_target, _end + 1, tmp, _start, _target.length - _end
                - 1);
        return tmp;
    }



    public static String delComments2(String inputCode) {
        int preType = 0;
        int mark = -1, cur = -1, token = -1;

        char[] input =  inputCode.toCharArray();
        for (cur = 0; cur < input.length; cur++) {
            if (input[cur] == Marks.MARK.mark) {
                // is it a escape char
                if (preType == Marks.BACKSLASH.ordinal()+1)
                    continue;
                // after a mark
                if (mark > 0) {
                    // after the end mark
                    mark = -1;
                } else {
                    mark = cur;
                }
                preType = Marks.MARK.ordinal()+1;
            } else if (input[cur] == Marks.SLASH.mark) {
                // inside mark
                if (mark > 0)
                    continue;
                // delete when STAR
                if (preType == Marks.STAR.ordinal()+1) {
                    input = del(input, token, cur);
                    // BACK
                    cur = token - 1;
                    preType = 0;
                } else if (preType == Marks.SLASH.ordinal()+1) {
                    token = cur - 1;
                    preType = Marks.DOUBLESLASH.ordinal()+1;
                } else {
                    preType = Marks.SLASH.ordinal()+1;
                }
            } else if (input[cur] == Marks.BACKSLASH.mark) {
                preType = Marks.BACKSLASH.ordinal()+1;
            } else if (input[cur] == Marks.STAR.mark) {
                // IN MARK
                if (mark > 0)
                    continue;
                // mark for slash start
                if (preType == Marks.SLASH.ordinal()+1) {
                    token = cur - 1;
                }
                preType = Marks.STAR.ordinal()+1;
            } else if(input[cur] == Marks.ENTER.mark)
            {
                if(preType == Marks.DOUBLESLASH.ordinal()+1)
                {
                    input = del(input, token, cur-1);
                    // back
                    cur = token;
                    preType = 0;
                }
            }

        }
        return new String(input);
    }



    enum Marks {
        MARK('"'),
        SLASH('/'),
        BACKSLASH('\\'),
        STAR ('*'),
        DOUBLESLASH ('/'),
        ENTER ('\n');//just for the ordinal
        private char mark;
        private Marks(char mark){
            this.mark = mark;
        }
    }
}

